固定IPなNLBをAWS CDKで構築する
AWS CDKでElastic IPを使った固定IPなNLB環境を作る機会があったので、TypeScriptのサンプルプログラムを共有します。
簡単にできるかなー?と、思っていたんですが、現状(2022/03/30)、cdkでNLBを作成するNetworkLoadBalancerクラスに、 Elastic IPを付与するパラメーターがありません。 正攻法では、NLBにEIPを設定することができないです。
CloudFormationであれば、以下ブログのようにEIPを使った固定IPなNLBを構築できます。
CloudFormationでできることは、ローレベルConstructを使えばだいたいcdkでもできるので、それを試します。
前提条件
AWS CDKはv2を使用しています
$ cdk --version 2.18.0 (build 75c90fa)
構成図
ざっくりこんな感じの環境を作ります。
AWS CDKのサンプルプログラム
TypeScriptのサンプルプログラムは次の通りです。
#!/usr/bin/env node import "source-map-support/register" import { Construct } from 'constructs' import { App, Stack, StackProps, Token } from 'aws-cdk-lib' import * as ec2 from 'aws-cdk-lib/aws-ec2' import * as elbv2 from 'aws-cdk-lib/aws-elasticloadbalancingv2' import * as elbv2Targtes from 'aws-cdk-lib/aws-elasticloadbalancingv2-targets' class TestStack extends Stack { constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); const vpc = new ec2.Vpc(this, 'VPC', { maxAzs: 2, natGateways: 0, subnetConfiguration: [{ name: 'PublicSubnet', subnetType: ec2.SubnetType.PUBLIC, }], }) // EC2作成 const securityGroup = new ec2.SecurityGroup(this, 'SecurityGroup', { vpc, allowAllOutbound: true, }) securityGroup.addIngressRule( ec2.Peer.anyIpv4(), ec2.Port.tcp(80), ) const bastion = new ec2.BastionHostLinux(this, 'EC2', { vpc, securityGroup, instanceType: ec2.InstanceType.of( ec2.InstanceClass.BURSTABLE4_GRAVITON, ec2.InstanceSize.MICRO, ), }) // NLB作成 const nlb = new elbv2.NetworkLoadBalancer(this, 'NLB', { vpc, internetFacing: true, vpcSubnets: { subnetType: ec2.SubnetType.PUBLIC, }, }) const nlbListener = nlb.addListener( 'NLBListener', { port: 80 }, ) nlbListener.addTargets('NLBTargets', { protocol: elbv2.Protocol.TCP, port: 80, targets: [ new elbv2Targtes.InstanceTarget( bastion.instance, 80 ) ] }) // NLBにEIPを付与する const cfnLoadBalancer = nlb.node.defaultChild as elbv2.CfnLoadBalancer cfnLoadBalancer.subnetMappings = vpc.publicSubnets.map((subnet, i) => { // パブリックサブネットのAZの数だけ、EIPを構築する const eip = new ec2.CfnEIP(this, `EIP${i}`,{ domain: 'vpc', }) nlb.node.addDependency(eip) // EIPを設定したNLBのSubnetMappingPropertyを作成する return { subnetId: subnet.subnetId, allocationId: Token.asString(eip.getAtt('AllocationId')), } as elbv2.CfnLoadBalancer.SubnetMappingProperty }) // NLBのSubnet設定を削除する if (cfnLoadBalancer.subnetMappings !== undefined) { cfnLoadBalancer.subnets = undefined } } } const app = new App(); new TestStack(app, 'TestStack');
解説
CloudFormationでNLBにEIPを設定して構築する場合は SubnetMappings
パラメーターを使って、EIPを設定します。
なので、cdkでも同じようにCloudFormationの SubnetMappings
パラメーターを設定してやります。
66行目で、NLBのdefaultChildから、CloudFormationと1:1になるL1コンストラクタのCfnLoadBalancerを取り出しています。
67〜79行目で、VPCのパブリックサブネットのAZの数だけSubnetMappingPropertyを作って、subnetMappingsに設定しています。
81〜83行目で、subnetMappingsを設定したので、重複しているとエラーとなるsubnetsのパラメーターを undefined
にして設定を削除しています。
この様に、subnetMappingsにElastic IPを設定して、デフォルトで設定されるsubnetsを無効にすることで、固定IPなNLBをAWS CDKで構築することができます。